/*
 * Copyright (c) 2009, Jan Pastor. All Rights Reserved.
 */

package sk.jp.commons.tools;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;

import sk.jp.commons.utils.FileUtil;

/**
 * Utility class for loading text or binary content from files or other resource
 * types.
 *
 * @author Jan Pastor 
 */
public class ResourceLoader {

    private ResourceLoader() {
    }

    //----------------------------------------------------------------------

    /**
     * Return an input stream to resource file <code>path</code>.
     * <p>Resource file can be placed in filesystem or in JAR file.
     *
     * @param path relative path from application directory to resource file.
     * @return input stream of resource content.
     * @throws FileNotFoundException if the resource file cannot be opened for
     * reading.
     */
    public static InputStream loadResourceFromPath(String path)
                                                throws FileNotFoundException {
        //First try read file from filesystem path:
        InputStream is;
        File f = new File(path);
        if(f.canRead()){
            is = new FileInputStream(f);
        }else{
            //...If not successful, search file in JARs:
            ClassLoader loader;
            loader = ResourceLoader.class.getClassLoader();
            is = loader.getResourceAsStream(path);
            if(is == null){
                throw new FileNotFoundException("The resource file '" +
                                                path + "' could not be found");
            }
        }
        return is;
    }

    /**
     * Loads specified resource file, located in CLASSPATH.
     * @param classLoader class loader to use. You can use
     * <code>getClass().getClassLoader()</code> to obtain it.
     * @param path path to resource file in classpath (e.g.
     * <i>"sk/ana/csp/conf/menu-config.xml"</i>).
     * @return input stream of resource content.
     * @throws FileNotFoundException if the resource could not be found.
     */
    public static InputStream loadResource(ClassLoader classLoader, String path)
                                    throws FileNotFoundException {
        InputStream is = classLoader.getResourceAsStream(path);
        if(is == null){
            throw new FileNotFoundException("Can't load file '" + path + "'");
        }
        return is;
    }

    /**
     * Loads specified binary resource file, located in CLASSPATH.
     * @param classLoader class loader to use. You can use
     * <code>getClass().getClassLoader()</code> to obtain it.
     * @param path path to resource file in classpath (e.g.
     * <i>"sk/ana/csp/img/arrowup.gif"</i>).
     * @return content of specified file.
     * @throws FileNotFoundException if the resource could not be found.
     * @throws Exception
     */
    public static byte[] loadBinaryResource(ClassLoader classLoader, String path)
                                        throws FileNotFoundException, Exception {
        InputStream is = null;
        try {
            is = loadResource(classLoader, path);
//            return FileUtil.getStreamContent(is);
            return FileUtil.getBytesFromStream(is);
        }finally{
            if(is != null){
                try {
                    is.close();
                }catch(Exception e2){
                    //ignore
                }
            }
        }
    }

    /**
     * Loads specified text resource file, located in CLASSPATH.
     * @param classLoader class loader to use. You can use
     * <code>getClass().getClassLoader()</code> to obtain it.
     * @param path path to resource file in classpath (e.g.
     * <i>"sk/ana/csp/conf/menu-config.xml"</i>).
     * @param charsetName charset name used to transform bytes to string. See
     * <code>new String(byte[] a, String charsetName)</code>.
     * @return content of specified file in String.
     * @throws FileNotFoundException if the resource could not be found.
     * @throws Exception
     */
    public static String loadStringResource(ClassLoader classLoader, String path,
                                            String charsetName)
                                        throws FileNotFoundException, Exception {
        byte[] content = loadBinaryResource(classLoader, path);
        return new String(content, charsetName);
    }

}
